package nio;

import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

public class NIOServer {
    public static void main(String[] args) throws IOException {
        Selector opAccepts = Selector.open();
        Selector opReads = Selector.open();

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8081));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(opAccepts, SelectionKey.OP_ACCEPT);
        new Thread(() -> {
            while (true){
                try {
                    if(opAccepts.select(1) > 0){
                        Iterator<SelectionKey> selectionKeyIterator = opAccepts.selectedKeys().iterator();
                        while (selectionKeyIterator.hasNext()){
                            SelectionKey selectionKey = selectionKeyIterator.next();
                            if(selectionKey.isAcceptable()){
                                SocketChannel socketChannel = ((ServerSocketChannel) selectionKey.channel()).accept();
                                socketChannel.configureBlocking(false);
                                socketChannel.register(opReads, SelectionKey.OP_READ);
                            }
                            if(!selectionKey.isConnectable()){
                                System.out.println("连接中断");
                            }
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
        }
        }).start();

        new Thread(() -> {
            try {
                while (true){
                    if(opReads.select(1) > 0){
                        Set<SelectionKey> set = opReads.selectedKeys();
                        Iterator<SelectionKey> keyIterator = set.iterator();
                        while (keyIterator.hasNext()){
                            SelectionKey selectionKey = keyIterator.next();
                            if(selectionKey.isReadable()){
                                try {
                                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                                    socketChannel.read(byteBuffer);
                                    byteBuffer.flip();
                                    System.out.println(StandardCharsets.UTF_8.decode(byteBuffer).toString());
                                }finally {
                                    keyIterator.remove();
                                    selectionKey.interestOps(SelectionKey.OP_READ);
                                }
                            }
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }).start();
    }
}
